package com.cro.prison.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cro.prison.dao.ErrorMessageDao;
import com.cro.prison.entity.constant.IDENTITYENUM;
import com.cro.prison.entity.constant.MESSAGESTATUSENUM;
import com.cro.prison.entity.constant.MESSAGETYPEENUM_CRIMINAL;
import com.cro.prison.entity.pojo.ErrorMessage;
import com.cro.prison.entity.vo.ErrorCountVo;
import com.cro.prison.service.ErrorMessageService;

import com.cro.prison.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.util.*;


@Service
public class ErrorMessageServiceImpl extends ServiceImpl<ErrorMessageDao, ErrorMessage> implements ErrorMessageService {

    @Autowired
    private ErrorMessageDao errorMessageDao;

    @Override
    public List<ErrorMessage> list() {

        List<ErrorMessage> list = errorMessageDao.list();
        return list;
    }

    @Override
    public List<Integer> SeriousErrList() {
        int length = 5;
        List list = new ArrayList(length*2);
        Calendar c = Calendar.getInstance();
        List<String> dateList = new ArrayList<>(5);
        for(int i = 0,day = 0;i<length;i++,day-=7){
            dateList.add(DateUtils.detailFormat(DateUtils.addDay(c.getTime(),day)));
        }
        for(int i = 0;i<length-1;i++){
            Integer err = getErrBetweenDate(
                    IDENTITYENUM.PRISONER.getCode()
                    , MESSAGETYPEENUM_CRIMINAL.FIGHT.getCode(),
                    dateList.get(i+1), dateList.get(i));
            list.add(err);
        }
        for(int i = 0;i<length-1;i++){
            Integer err = getErrBetweenDate(IDENTITYENUM.PRISONER.getCode(),
                    MESSAGETYPEENUM_CRIMINAL.GUARD_AREA.getCode(),
                    dateList.get(i+1), dateList.get(i));
            list.add(err);
        }
        return list;
    }

    /**
     * 查询违规记录并按日期统计次数
     * @param list
     * @param start
     * @return int[]
     **/
    @Override
    public int[] queryViolationRecords(List<ErrorMessage> list, String start) {

        HashMap<java.util.Date, Integer> map = new HashMap<>();

        for (ErrorMessage errorMessage : list) {
            Integer times = map.getOrDefault(errorMessage.getCreateTime(), 0);
            map.put(errorMessage.getCreateTime(), times + 1);
        }

        Date startDate = Date.valueOf(start);
        int[] dateTimes = new int[7];
        Set<Map.Entry<java.util.Date, Integer>> entries = map.entrySet();
        for (Map.Entry<java.util.Date, Integer> entry : entries) {
            int index = (int) ((entry.getKey().getTime() - startDate.getTime() )/ (24 * 60 * 60 * 1000));
            dateTimes[index] = entry.getValue();
        }

        return dateTimes;
    }

    @Override
    public void updateErrorMessage(Long id, String description) {
        ErrorMessage errorMessage = this.baseMapper.selectById(id);
        errorMessage.setDescription(description);
        errorMessage.setStatus(MESSAGESTATUSENUM.SOLVED.getCode());
        this.baseMapper.updateById(errorMessage);
    }

    @Override
    public List<ErrorCountVo> getTotalErrCount() {
        //获取 异常视频数量，狱警违规次数，罪犯违规次数
        List<ErrorMessage> list = errorMessageDao.list();
        int prisonCount = 0;
        int policeCount = 0;
        int videoCount = 0;
        for(ErrorMessage cur:list){
            if(cur.getIdentity() == 1){
                prisonCount++;
            }else{
                policeCount++;
            }
            if(cur.getVideoSrc() != null) videoCount++;
        }
        ErrorCountVo pc = new ErrorCountVo();
        pc.setName("狱警违规次数");
        pc.setCount(policeCount);
        ErrorCountVo prisonVo = new ErrorCountVo();
        prisonVo.setName("罪犯违规次数");
        prisonVo.setCount(prisonCount);
        ErrorCountVo vc = new ErrorCountVo();
        vc.setName("已经记录的视频数");
        vc.setCount(videoCount);
        List<ErrorCountVo> res = new ArrayList<>();
        res.add(pc);
        res.add(prisonVo);
        res.add(vc);

        return res;
    }

    private Integer getErrBetweenDate(Integer identity,Integer type,String startDate,String endDate){
        LambdaQueryWrapper<ErrorMessage> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(ErrorMessage::getIdentity,identity);
        lambdaQueryWrapper.eq(ErrorMessage::getType,type);
        lambdaQueryWrapper.between(ErrorMessage::getCreateTime,startDate,endDate);
        return this.baseMapper.selectCount(lambdaQueryWrapper);
    }
}
